///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __ShadowCameraSetupLiSPSM_H__
#define __ShadowCameraSetupLiSPSM_H__

#include "OgrePrerequisites.h"
#include "OgreShadowCameraSetupFocused.h"


namespace Ogre 
{

	
	
	
	class _OgreExport LiSPSMShadowCameraSetup : public FocusedShadowCameraSetup
	{
	protected:
		/// Warp factor adjustment
		Real mOptAdjustFactor;
		/// Use simple nopt derivation?
		bool mUseSimpleNOpt;
		/// Extra calculated warp factor
		mutable Real mOptAdjustFactorTweak;
		/// Threshold (cos angle) within which to start increasing the opt adjust as camera direction approaches light direction
		Real mCosCamLightDirThreshold;

		
		Matrix4 calculateLiSPSM(const Matrix4& lightSpace, const PointListBody& bodyB, 
			const PointListBody& bodyLVS, const SceneManager& sm, 
			const Camera& cam, const Light& light) const;

		
		Real calculateNOpt(const Matrix4& lightSpace, const AxisAlignedBox& bodyBABB_ls, 
			const PointListBody& bodyLVS, const Camera& cam) const;

		
		Real calculateNOptSimple(const PointListBody& bodyLVS, 
			const Camera& cam) const;

		
		Vector3 calculateZ0_ls(const Matrix4& lightSpace, const Vector3& e, Real bodyB_zMax_ls, 
			const Camera& cam) const;

		
		Matrix4 buildFrustumProjection(Real left, Real right, Real bottom, 
			Real top, Real near, Real far) const;

	public:
		
		LiSPSMShadowCameraSetup(void);

		
		virtual ~LiSPSMShadowCameraSetup(void);

		
		virtual void getShadowCamera(const SceneManager *sm, const Camera *cam, 
			const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const;

		
		virtual void setOptimalAdjustFactor(Real n) { mOptAdjustFactor = n; }
		
		virtual Real getOptimalAdjustFactor() const { return mOptAdjustFactor; }
		
		virtual void setUseSimpleOptimalAdjust(bool s) { mUseSimpleNOpt = s; }
		
		virtual bool getUseSimpleOptimalAdjust() const { return mUseSimpleNOpt; }

		
		virtual void setCameraLightDirectionThreshold(Degree angle);

		
		virtual Degree getCameraLightDirectionThreshold() const;


	};
	
	

}

#endif

